home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / dopus412-gpl / program / main18.c < prev    next >
C/C++ Source or Header  |  2000-02-28  |  14KB  |  566 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "DOpus.h"
  32.  
  33. struct recurse {
  34.     struct recurse *last;
  35.     char *dir,*dest;
  36.     int data;
  37.     APTR data2;
  38.     APTR data3;
  39.     BPTR lock;
  40.     struct FileInfoBlock *info;
  41. };
  42.  
  43. struct makedirlist {
  44.     struct makedirlist *last,*next;
  45.     char *path;
  46. };
  47.  
  48. struct recurse *current_recurse;
  49.  
  50. recursedir(fdir,fdest,dowhat,fdata)
  51. char *fdir,*fdest;
  52. int dowhat,fdata;
  53. {
  54.     BPTR mylock;
  55.     struct FileInfoBlock __aligned myfinfo;
  56.     struct FileInfoBlock __aligned enfinfo;
  57.     char *name,*dir,*dest,*dname,*ddir,*adir,*adest,*ndir,*ndest;
  58.     int suc,cont,ret,a,err,w1=1-data_active_window,adata,depth,b,rtry,data,*pstuff,blocks;
  59.     struct recpath *crec=NULL,*trec;
  60.     struct RecursiveDirectory
  61.         *cur_recurse,*addparent_recurse,*new_rec,*pos_rec,*cur_parent,
  62.         *cur_lastparent=NULL;
  63.     APTR data2=NULL,adata2=NULL,data3=NULL,adata3=NULL;
  64.     struct DOpusRemember *recurserem=NULL;
  65.     struct makedirlist *first_makedir=NULL;
  66.  
  67.     if (dowhat&R_STARDIR) {
  68.         rec_firstpath=NULL;
  69.         rec_pathkey=NULL;
  70.     }
  71.  
  72.     if (dowhat&R_GETNAMES) {
  73.         first_recurse=NULL;
  74.         recurse_dir_key=NULL;
  75.         cur_recurse=NULL;
  76.         addparent_recurse=NULL;
  77.     }
  78.  
  79.     data=fdata;
  80.  
  81.     current_recurse=NULL; ret=depth=0; recurse_max_depth=0;
  82.     dos_global_bytecount=0;
  83.     dos_global_copiedbytes=0;
  84.     dos_global_deletedbytes=0;
  85.     dos_global_blocksneeded=0;
  86.  
  87.     if (!(mylock=Lock(fdir,ACCESS_READ))) {
  88.         doerror(IoErr());
  89.         return(-1);
  90.     }
  91.     Examine(mylock,&myfinfo);
  92.  
  93.     if (!(name=LAllocRemember(&recurserem,2560,MEMF_CLEAR))) {
  94.         doerror(IoErr());
  95.         ret=-1;
  96.         goto goaway;
  97.     }
  98.     dir=name+512; dest=name+1024; dname=name+1536; ddir=name+2048;
  99.     if (fdir) strcpy(dir,fdir);
  100.     if (fdest) strcpy(dest,fdest);
  101.  
  102.     if (dowhat&R_COPY) {
  103.         strcpy(ddir,dest);
  104.         if (!(a=copymakedir(&recurserem,&first_makedir,dest,&myfinfo)) || a==-1) {
  105.             UnLock(mylock);
  106.             if (a==0) ret=-3;
  107.             else ret=-10;
  108.             goto goaway;
  109.         }
  110.     }
  111.     cont=ExNext(mylock,&myfinfo);
  112.  
  113.     FOREVER {
  114.         if (status_haveaborted) {
  115.             myabort();
  116.             ret=-10;
  117.             break;
  118.         }
  119.         if (!cont) {
  120.             if (current_recurse) {
  121.                 if (mylock) UnLock(mylock);
  122.                 strcpy(dname,dir);
  123.                 mylock=current_recurse->lock;
  124.                 CopyMem((char *)current_recurse->info,(char *)&myfinfo,sizeof(struct FileInfoBlock));
  125.                 strcpy(dir,current_recurse->dir);
  126.                 strcpy(dest,current_recurse->dest);
  127.                 data=current_recurse->data;
  128.                 data2=current_recurse->data2;
  129.                 data3=current_recurse->data3;
  130.                 current_recurse=current_recurse->last;
  131.  
  132.                 strcpy(name,dir);
  133.                 TackOn(name,myfinfo.fib_FileName,512);
  134.  
  135.                 if (dowhat&R_GETNAMES) {
  136.                     cur_recurse=(struct RecursiveDirectory *)data2;
  137.                     cur_lastparent=(struct RecursiveDirectory *)data3;
  138.                     addparent_recurse=NULL;
  139.                 }
  140.  
  141.                 if (dowhat&R_COPY) {
  142.                     strcpy(ddir,dest);
  143.                     if (config->copyflags©_DATE) {
  144.                         TackOn(ddir,myfinfo.fib_FileName,512);
  145.                         setdate(ddir,&myfinfo.fib_Date);
  146.                         strcpy(ddir,dest);
  147.                     }
  148.                 }
  149.  
  150.                 a=0;
  151.                 if (dowhat&R_COMMENT) {
  152.                     FOREVER {
  153.                         if (!(SetComment(name,dest))) {
  154.                             err=IoErr();
  155.                             doerror(err);
  156.                             a=checkerror(globstring[STR_COMMENTING],myfinfo.fib_FileName,err);
  157.                             if (a==1) continue;
  158.                         }
  159.                         break;
  160.                     }
  161.                     if (a==3) break;
  162.                 }
  163.  
  164.                 if (dowhat&R_PROTECT) {
  165.                     pstuff=(int *)data;
  166.                     b=getnewprot(myfinfo.fib_Protection,pstuff[0],pstuff[1]);
  167.                     FOREVER {
  168.                         if (!(SetProtection(name,b))) {
  169.                             err=IoErr();
  170.                             doerror(err);
  171.                             a=checkerror(globstring[STR_PROTECTING],myfinfo.fib_FileName,err);
  172.                             if (a==1) continue;
  173.                         }
  174.                         break;
  175.                     }
  176.                     if (a==3) break;
  177.                 }
  178.  
  179.                 if (dowhat&R_DATESTAMP) {
  180.                     FOREVER {
  181.                         if ((err=setdate(name,(struct DateStamp *)data))!=1) {
  182.                             doerror(err);
  183.                             a=checkerror(globstring[STR_DATESTAMPING],myfinfo.fib_FileName,err);
  184.                             if (a==1) continue;
  185.                         }
  186.                         break;
  187.                     }
  188.                     if (a==3) break;
  189.                 }
  190.  
  191.                 cont=ExNext(mylock,&myfinfo);
  192.  
  193.                 if (dowhat&R_DELETE && depth>0) {
  194.                     a=strlen(dname);
  195.                     if (a>0 && dname[a-1]=='/') dname[a-1]=0;
  196.                     if ((a=delfile(dname,BaseName(dname),globstring[STR_DELETING],
  197.                         glob_unprotect_all,1))==-1) {
  198.                         myabort();
  199.                         ret=-10;
  200.                         break;
  201.                     }
  202.                     if (a==2) glob_unprotect_all=1;
  203.                 }
  204.                 --depth;
  205.                 continue;
  206.             }
  207.             else break;
  208.         }
  209.         CopyMem((char *)&myfinfo,(char *)&enfinfo,sizeof(struct FileInfoBlock));
  210.  
  211.         strcpy(name,dir);
  212.         TackOn(name,enfinfo.fib_FileName,512);
  213.  
  214.         if (enfinfo.fib_DirEntryType>0) {
  215.             ++dos_global_blocksneeded;
  216.             if (enfinfo.fib_DirEntryType!=4) {
  217.                 adir=NULL;
  218.                 dofilename(name);
  219.                 if (dowhat&R_GETNAMES) {
  220.                     if (new_rec=LAllocRemember(&recurse_dir_key,sizeof(struct RecursiveDirectory),MEMF_CLEAR)) {
  221.                         strcpy(new_rec->name,enfinfo.fib_FileName);
  222.                         CopyMem((char *)&enfinfo.fib_Date,(char *)&new_rec->date,sizeof(struct DateStamp));
  223.                         if (addparent_recurse) {
  224.                             addparent_recurse->child=new_rec;
  225.                             cur_lastparent=addparent_recurse;
  226.                             cur_recurse=new_rec;
  227.                         }
  228.                         else if (!first_recurse) {
  229.                             first_recurse=new_rec;
  230.                             cur_recurse=new_rec;
  231.                         }
  232.                         else if (cur_recurse) {
  233.                             if (LStrCmpI(new_rec->name,cur_recurse->name)<0) {
  234.                                 if (first_recurse==cur_recurse) first_recurse=new_rec;
  235.                                 if (cur_lastparent && cur_lastparent->child==cur_recurse)
  236.                                     cur_lastparent->child=new_rec;
  237.                                 new_rec->next=cur_recurse;
  238.                                 cur_recurse=new_rec;
  239.                             }
  240.                             else {
  241.                                 pos_rec=cur_recurse;
  242.                                 FOREVER {
  243.                                     if (!pos_rec->next ||
  244.                                         (LStrCmpI(new_rec->name,pos_rec->next->name)<0)) {
  245.                                         new_rec->next=pos_rec->next;
  246.                                         pos_rec->next=new_rec;
  247.                                         break;
  248.                                     }
  249.                                     pos_rec=pos_rec->next;
  250.                                 }
  251.                             }
  252.                         }
  253.                         else cur_recurse=new_rec;
  254.                         cur_parent=new_rec;
  255.                     }
  256.                     adir=dir; adest=dest; ndir=name; ndest=dest;
  257.                     adata2=(APTR)cur_recurse;
  258.                     adata3=(APTR)cur_lastparent;
  259.                     addparent_recurse=cur_parent;
  260.                 }
  261.                 strcpy(dname,dest);
  262.                 if (dowhat&R_COPY) {
  263.  
  264.                     dotaskmsg(hotkeymsg_port,PROGRESS_UPDATE,-2,0,enfinfo.fib_FileName,1);
  265.  
  266.                     TackOn(dname,enfinfo.fib_FileName,512);
  267.                     adir=dir; adest=dest; adata=data; ndir=name; ndest=dname;
  268.                     strcpy(ddir,dname);
  269.                     if ((a=copymakedir(&recurserem,&first_makedir,ddir,&enfinfo))==-1) {
  270.                         ret=-10;
  271.                         break;
  272.                     }
  273.                     else if (a==0) adir=NULL;
  274.                 }
  275.                 if (dowhat&R_DELETE) {
  276.                     rtry=1;
  277. delloop:
  278.                     if (!DeleteFile(name)) {
  279.                         if (config->deleteflags&8 && rtry==1 && IoErr()==222) {
  280.                             rtry=0;
  281.                             SetProtection(name,0);
  282.                             goto delloop;
  283.                         }
  284.                         adir=dir; adest=dest; adata=data; ndir=name; ndest=dname;
  285.                     }
  286.                     else {
  287.                         if (config->dynamicflags&1) seename(data_active_window);
  288.                         adir=NULL;
  289.                     }
  290.                 }
  291.                 if (dowhat&R_HUNT || dowhat&R_SEARCH || dowhat&R_COMMENT ||
  292.                     dowhat&R_PROTECT || dowhat&R_DATESTAMP || dowhat&R_GETBYTES ||
  293.                     dowhat&R_STARDIR) {
  294.                     adir=dir; adest=dest; adata=data; ndir=name; ndest=dest;
  295.                     adata2=data2; adata3=data3;
  296.                 }
  297.                 if (adir) {
  298.                     if (!(addrecurse(&recurserem,adir,adest,adata,adata2,adata3,mylock,&enfinfo))) {
  299.                         cont=0;
  300.                         continue;
  301.                     }
  302.                     strcpy(dir,ndir);
  303.                     strcpy(dest,ndest);
  304.                     if (!(mylock=Lock(dir,ACCESS_READ))) {
  305.                         cont=0;
  306.                         continue;
  307.                     }
  308.                     Examine(mylock,&myfinfo);
  309.                     cont=ExNext(mylock,&myfinfo);
  310.                     ++depth;
  311.                     if (depth>recurse_max_depth) recurse_max_depth=depth;
  312.                     continue;
  313.                 }
  314.             }
  315.         }
  316.         cont=ExNext(mylock,&myfinfo);
  317.  
  318.         if (enfinfo.fib_DirEntryType<0) {
  319.             a=0;
  320.             dos_global_bytecount+=enfinfo.fib_Size;
  321.             if (dowhat&R_GETBYTES && data) {
  322.                 blocks=(enfinfo.fib_Size+(data-1))/data;
  323.                 dos_global_blocksneeded+=blocks+(blocks/72)+1;
  324.             }
  325.  
  326.             if (dowhat&R_GETNAMES) goto skipgetnam;
  327.             dofilename(name);
  328.             if (dowhat&R_STARDIR) {
  329.                 if ((trec=LAllocRemember(&rec_pathkey,sizeof(struct recpath),MEMF_CLEAR)) &&
  330.                     (trec->path=LAllocRemember(&rec_pathkey,(strlen(name)+1)-data,MEMF_CLEAR))) {
  331.                     trec->next=NULL;
  332.                     strcpy(trec->path,&name[data]);
  333.                     if (crec) crec->next=trec;
  334.                     crec=trec;
  335.                     if (!rec_firstpath) rec_firstpath=trec;
  336.                 }
  337.             }
  338.             if (!str_filter_parsed[0] ||
  339.                 LMatchPatternI(str_filter_parsed,enfinfo.fib_FileName)) {
  340.                 if (dowhat&R_COPY) {
  341.                     strcpy(dname,ddir);
  342.                     TackOn(dname,enfinfo.fib_FileName,512);
  343.  
  344.                     dotaskmsg(hotkeymsg_port,PROGRESS_UPDATE,-2,0,enfinfo.fib_FileName,1);
  345.  
  346.                     a=0;
  347.                     FOREVER {
  348.                         if (!(a=copyfile(name,dname,&err,-1,NULL,0))) {
  349.                             doerror(err);
  350.                             a=checkerror(globstring[STR_COPYING],enfinfo.fib_FileName,err);
  351.                             if (a==1) continue;
  352.                             if (a!=3) seename(data_active_window);
  353.                         }
  354.                         else if (a==-1) {
  355.                             myabort();
  356.                             a=3;
  357.                             break;
  358.                         }
  359.                         else {
  360.                             if (dowhat==R_COPY) {
  361.                                 if (config->copyflags©_ARC && !(enfinfo.fib_Protection&FIBF_ARCHIVE))
  362.                                     SetProtection(name,enfinfo.fib_Protection|FIBF_ARCHIVE);
  363.                             }
  364.                             dos_global_copiedbytes+=enfinfo.fib_Size;
  365.                         }
  366.                         if (config->dynamicflags&1) seename(data_active_window);
  367.                         break;
  368.                     }
  369.                     if (a==3) {
  370.                         ret=-10;
  371.                         break;
  372.                     }
  373.                     if (config->dynamicflags&1) {
  374.                         seename(data_active_window); seename(w1);
  375.                     }
  376.                 }
  377.                 if (dowhat&R_DELETE) {
  378.                     if ((a=delfile(name,enfinfo.fib_FileName,globstring[STR_DELETING],
  379.                         glob_unprotect_all,1))==-1) {
  380.                         myabort();
  381.                         ret=-10;
  382.                         break;
  383.                     }
  384.                     if (a==2) glob_unprotect_all=1;
  385.                     if (config->dynamicflags&1) seename(data_active_window);
  386.                     dos_global_deletedbytes+=enfinfo.fib_Size;
  387.                 }
  388.                 if (dowhat&R_COMMENT) {
  389.                     FOREVER {
  390.                         if (!(SetComment(name,dest))) {
  391.                             err=IoErr();
  392.                             doerror(err);
  393.                             a=checkerror(globstring[STR_COMMENTING],enfinfo.fib_FileName,err);
  394.                             if (a==1) continue;
  395.                         }
  396.                         break;
  397.                     }
  398.                     if (a==3) {
  399.                         ret=-10;
  400.                         break;
  401.                     }
  402.                 }
  403.                 if (dowhat&R_PROTECT) {
  404.                     pstuff=(int *)data;
  405.                     b=getnewprot(enfinfo.fib_Protection,pstuff[0],pstuff[1]);
  406.                     FOREVER {
  407.                         if (!(SetProtection(name,b))) {
  408.                             err=IoErr();
  409.                             doerror(err);
  410.                             a=checkerror(globstring[STR_PROTECTING],enfinfo.fib_FileName,err);
  411.                             if (a==1) continue;
  412.                         }
  413.                         break;
  414.                     }
  415.                     if (a==3) {
  416.                         ret=-10;
  417.                         break;
  418.                     }
  419.                 }
  420.                 if (dowhat&R_DATESTAMP) {
  421.                     FOREVER {
  422.                         if ((err=setdate(name,(struct DateStamp *)data))!=1) {
  423.                             err=IoErr();
  424.                             doerror(err);
  425.                             a=checkerror(globstring[STR_DATESTAMPING],enfinfo.fib_FileName,err);
  426.                             if (a==1) continue;
  427.                         }
  428.                         break;
  429.                     }
  430.                     if (a==3) {
  431.                         ret=-10;
  432.                         break;
  433.                     }
  434.                 }
  435.                 if (dowhat&R_HUNT) {
  436.                     suc=huntfile(enfinfo.fib_FileName,name,&a);
  437.                     ret+=a;
  438.                     if (suc) {
  439.                         if (suc==-1) {
  440.                             myabort();
  441.                             ret=-10;
  442.                         }
  443.                         else ret=suc;
  444.                         break;
  445.                     }
  446.                 }
  447.                 if (dowhat&R_SEARCH) {
  448.                     suc=filesearch(name,&a,0);
  449.                     ret+=a;
  450.                     busy();
  451.                     if (suc==2) {
  452.                         if (!simplerequest(globstring[STR_CONTINUE_WITH_SEARCH],
  453.                             globstring[STR_CONTINUE],str_cancelstring,NULL)) {
  454.                             okay();
  455.                             ret=-2;
  456.                             break;
  457.                         }
  458.                     }
  459. skipgetnam:
  460.                     if (suc==-1) {
  461.                         myabort();
  462.                         ret=-10;
  463.                         break;
  464.                     }
  465.                 }
  466.             }
  467.         }
  468.     }
  469.     if (mylock) UnLock(mylock);
  470.     while (current_recurse) {
  471.         UnLock(current_recurse->lock);
  472.         current_recurse=current_recurse->last;
  473.     }
  474.     if (first_makedir &&
  475.         dowhat==R_COPY &&
  476.         str_filter_parsed[0]) {
  477.  
  478.         struct makedirlist *last;
  479.  
  480.         last=first_makedir;
  481.         while (last->next) last=last->next;
  482.  
  483.         while (last) {
  484.             DeleteFile(last->path);
  485.             last=last->last;
  486.         }
  487.     }
  488. goaway:
  489.     if (recurserem) LFreeRemember(&recurserem);
  490.     return(ret);
  491. }
  492.  
  493. addrecurse(key,dir,dest,data,data2,data3,lock,info)
  494. struct DOpusRemember **key;
  495. char *dir,*dest;
  496. int data;
  497. APTR data2,data3;
  498. BPTR lock;
  499. struct FileInfoBlock *info;
  500. {
  501.     struct recurse *rec;
  502.  
  503.     if (!(rec=LAllocRemember(key,sizeof(struct recurse),MEMF_CLEAR)))
  504.         return(0);
  505.     if (current_recurse) rec->last=current_recurse;
  506.     else rec->last=NULL;
  507.     if (!(rec->dir=LAllocRemember(key,strlen(dir)+1,MEMF_CLEAR)) ||
  508.         !(rec->dest=LAllocRemember(key,strlen(dest)+1,MEMF_CLEAR)))
  509.         return(0);
  510.     strcpy(rec->dir,dir); strcpy(rec->dest,dest);
  511.     rec->data=data;
  512.     rec->data2=data2;
  513.     rec->data3=data3;
  514.     rec->lock=lock;
  515.     if (!(rec->info=LAllocRemember(key,sizeof(struct FileInfoBlock),0)))
  516.         return(0);
  517.     CopyMem((char *)info,(char *)rec->info,sizeof(struct FileInfoBlock));
  518.     current_recurse=rec;
  519.     return(1);
  520. }
  521.  
  522. copymakedir(key,first,dirname,finfo)
  523. struct DOpusRemember **key;
  524. struct makedirlist **first;
  525. char *dirname;
  526. struct FileInfoBlock *finfo;
  527. {
  528.     int exist,a,err;
  529.     BPTR mylock;
  530.  
  531.     exist=CheckExist(dirname,NULL);
  532.     if (exist<=0) {
  533. loop:
  534.         if (exist<0 || !(mylock=CreateDir(dirname))) {
  535.             if (exist<0) err=203;
  536.             else err=IoErr();
  537.             doerror(err);
  538.             a=checkerror(globstring[STR_CREATING],finfo->fib_FileName,err);
  539.             if (a==1) goto loop;
  540.             if (a==2) return(0);
  541.             return(-1);
  542.         }
  543.         if (mylock) {
  544.             struct makedirlist *list,*pos;
  545.  
  546.             UnLock(mylock);
  547.  
  548.             if (config->copyflags©_DATE) setdate(dirname,&finfo->fib_Date);
  549.             if (config->copyflags©_PROT) SetProtection(dirname,finfo->fib_Protection);
  550.             if (config->copyflags©_NOTE) SetComment(dirname,finfo->fib_Comment);
  551.  
  552.             if ((list=LAllocRemember(key,sizeof(struct makedirlist),MEMF_CLEAR)) &&
  553.                 (list->path=LAllocRemember(key,strlen(dirname)+1,0))) {
  554.                 strcpy(list->path,dirname);
  555.                 if (!(pos=*first)) *first=list;
  556.                 else {
  557.                     while (pos->next) pos=pos->next;
  558.                     pos->next=list;
  559.                     list->last=pos;
  560.                 }
  561.             }
  562.         }
  563.     }
  564.     return(1);
  565. }
  566.